package com.thoughtservice.jspdoc.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Iterator;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.thoughtservice.jspdoc.DirTree;
import com.thoughtservice.jspdoc.data.Defenition;
import com.thoughtservice.jspdoc.data.DefenitionPuts;
import com.thoughtservice.jspdoc.data.TilesDefinitions;
import com.thoughtworks.xstream.XStream;

public class TilesUtils {

	private final static Logger LOG = LoggerFactory.getLogger(TilesUtils.class);
			
	private static XStream xstream = new XStream();

	// This map is for faster processing of tiles. Contains the tile definition
	// name as key and path as value
	private static Multimap<String, String> tilesMap = LinkedHashMultimap.create();	

	static {
		xstream.processAnnotations(TilesDefinitions.class);
		xstream.processAnnotations(Defenition.class);
		xstream.processAnnotations(DefenitionPuts.class);

		FileInputStream is;
		try {
			LOG.trace("Entering static block of {}", TilesUtils.class.getName());
			//"C:/shinu/java/StrutsExample/src/main/webapp/WEB-INF/tiles-defs.xml"
			//C:/IBM/WCDE_ENT70/workspace/StrutsExample/src/main/webapp/WEB-INF/tiles-defs.xml
			//There can be more than one tiles-defs. Get all defs starts with tiles-defs
			
			//Iterate over all tile defs and process xstream
			//
			//"C:/IBM/WCDE_ENT70/workspace/Stores/WebContent/WEB-INF"
			Iterator<File> it = FileUtils.iterateFiles(new File(DirTree.rootSourceDir+"/WEB-INF"), new String[]{"xml"}, false);
			
			while(it.hasNext()){
				File f = it.next();
				if(f.getName().startsWith("tiles-defs")){
					LOG.debug("Processing file -->"+f.getAbsolutePath());
					
					is = new FileInputStream(f);

					InputStreamReader isr = new InputStreamReader(is, "UTF-8");

					TilesDefinitions defenitions = (TilesDefinitions) xstream
							.fromXML(isr);
					if(defenitions != null && defenitions.getDefinition() != null){
						for (Defenition defs : defenitions.getDefinition()) {
							tilesMap.put(defs.getName(), defs.getPath());
							LOG.debug("{} : {}",defs.getName(), defs.getPath());
							if (defs.getPut() != null) {
								for (DefenitionPuts put : defs.getPut()) {
									LOG.debug("{} : {}", put.getName(), put.getValue());
									// Process the puts
									tilesMap.put(put.getName(), put.getValue());
								}
							}
						}
					}//if end					
				}
			}
			
			//Make it to debug enabled and save it to a file for checking
			LOG.debug("Total Tile Map count -->"+tilesMap.size());
					
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LOG.error("{}", ExceptionUtils.getFullStackTrace(e));
		} 
		LOG.trace("Exiting static block of {}", TilesUtils.class.getName());
	}

	public static String[] figureLink(String defenitionName) {
		LOG.trace("Entering {}", "figureLink");
		if (defenitionName == null)
			return null;
		if (tilesMap.containsKey(defenitionName)) {
			return tilesMap.get(defenitionName).toArray(new String[]{});			
		}
		LOG.trace("Exiting {}", "figureLink");
		return null;
	}
	
	/**
	 * Return the first element alone
	 * @param definitionName
	 * @return
	 */
	public static String getTileDefs(String definitionName){
		LOG.trace("Entering {}", "getTileDefs");
		if (definitionName == null)
			return null;
		if (tilesMap.containsKey(definitionName)) {
			return tilesMap.get(definitionName).toArray(new String[]{})[0];			
		}
		LOG.trace("Exiting {}", "getTileDefs");
		return null;
	}

	public static void main(String[] args) {
		new TilesUtils();
	}
}
